// Package ginx 第六周作业中写的东西，没有太理解，暂时没有使用
package ginx

import (
	"JK-Junior-Go-Engineer-Camp/webook/pkg/logger"
	"github.com/gin-gonic/gin"
	"net/http"
)

var L logger.LoggerV1 = logger.NewNopLogger()

// WrapBodyAndClaims 利用泛型解决web层下的 Bind参数+取出UserClaims 这种模板化代码
// bizFunc 业务逻辑（business Func)
func WrapBodyAndClaims[Req any, Claims any](
	bizFunc func(ctx *gin.Context, req Req, claims Claims) (Result, error),
) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var req Req
		if err := ctx.Bind(&req); err != nil {
			L.Error("输入参数错误", logger.Error(err))
			return
		}

		L.Debug("执行业务逻辑的参数", logger.Field{Key: "req", Val: req})
		val, ok := ctx.Get("user")
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		uc, ok := val.(Claims)
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		res, err := bizFunc(ctx, req, uc)
		if err != nil {
			L.Error("执行业务逻辑失败", logger.Error(err))
		}
		ctx.JSON(http.StatusOK, res)
	}
}

// WrapBody 利用泛型解决web层下的 Bind参数 这种模板化代码
func WrapBody[Req any](
	bizFunc func(ctx *gin.Context, req Req) (Result, error),
) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		var req Req
		if err := ctx.Bind(&req); err != nil {
			L.Error("输入参数错误", logger.Error(err))
			return
		}

		L.Debug("执行业务逻辑的参数", logger.Field{Key: "req", Val: req})

		res, err := bizFunc(ctx, req)
		if err != nil {
			L.Error("执行业务逻辑失败", logger.Error(err))
		}
		ctx.JSON(http.StatusOK, res)
	}
}

// WrapClaims 利用泛型解决web层下的 取出UserClaims 这种模板化代码
func WrapClaims[Claims any](
	bizFunc func(ctx *gin.Context, claims Claims) (Result, error),
) gin.HandlerFunc {
	return func(ctx *gin.Context) {
		val, ok := ctx.Get("user")
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		uc, ok := val.(Claims)
		if !ok {
			ctx.AbortWithStatus(http.StatusUnauthorized)
		}
		res, err := bizFunc(ctx, uc)
		if err != nil {
			L.Error("执行业务逻辑失败", logger.Error(err))
		}
		ctx.JSON(http.StatusOK, res)
	}
}
